#ifndef __CONDTION_H__
#define __CONDTION_H__

#include <pthread.h>
#include <cassert>
#include <time.h>
#include <stdint.h>
#include "Mutex.h"

class Condtion
{
public:
    Condtion(Mutex &mutex)
        : mMutex(mutex)
    {
        int err = pthread_cond_init(&mCond, NULL);
        assert(err == 0); (err);
    }
    ~Condtion()
    {
        pthread_cond_destroy(&mCond);
    }
    void Wait()
    {
        pthread_cond_wait(&mCond, mMutex.GetPthreadMutex());
    }
    bool WaitTimeout(double delay)
    {
        const int64_t kNanosecondsPerSec = 1000 * 1000 * 1000;
        struct timespec tp;
        clock_gettime(CLOCK_REALTIME, &tp);
        int64_t tick = tp.tv_sec * kNanosecondsPerSec + tp.tv_nsec;
        tick += (int64_t)(delay * kNanosecondsPerSec);
        tp.tv_sec = tick / kNanosecondsPerSec;
        tp.tv_nsec = tick % kNanosecondsPerSec;
        return (0 != pthread_cond_timedwait(&mCond, mMutex.GetPthreadMutex(), &tp));
    }
    void Signal()
    {
        pthread_cond_signal(&mCond);
    }
    void SignalAll()
    {
        pthread_cond_broadcast(&mCond);
    }

private:
    Mutex &mMutex;
    pthread_cond_t mCond;

private:
    Condtion(const Condtion&);
    Condtion& operator=(const Condtion&);
};

#endif
